<?php
namespace frame;
/**
 * Frame 应用程序类 执行应用过程管理
 */
class App{
	/**
     * 应用程序初始化
     * @access public
     * @return void
     */
    static public function init() {
        //1.定义当前请求的系统常量
        define('NOW_TIME',      $_SERVER['REQUEST_TIME']);
        define('REQUEST_METHOD',$_SERVER['REQUEST_METHOD']);
        //define('REQUEST_METHOD',isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET');
        define('IS_GET',        REQUEST_METHOD =='GET' ? true : false);
        define('IS_POST',       REQUEST_METHOD =='POST' ? true : false);
        define('IS_PUT',        REQUEST_METHOD =='PUT' ? true : false);
        define('IS_DELETE',     REQUEST_METHOD =='DELETE' ? true : false);

        //2.加载动态应用公共文件和配置(common/conf和common/common)
        load_ext_file(COMMON_PATH);

        //3.日志目录转换为绝对路径 默认情况下存储到公共模块下面
        C('LOG_PATH',   realpath(LOG_PATH).'common/');
        //4.URL调度
        Dispatcher::dispatch();
        return ;
    }

	 /**
     * 运行应用实例 入口文件使用的快捷方法
     * @access public
     * @return void
     */
    static public function run() {
        //1.应用程序初始化
        App::init();
        //2.记录应用初始化时间
        //G('initTime');
        // Session初始化(非命令行    )
        if(!IS_CLI){
            //session(C('SESSION_OPTIONS'));
        }
        //3.执行应用程序
        App::exec();
        return ;
    }

    /**
     * 执行应用程序
     * @access public
     * @return void
     */
    static public function exec() {
        if(!preg_match('/^[A-Za-z](\/|\w)*$/',CONTROLLER_NAME)){ // 安全检测(可支持多级控制器)
            $ctrl  =  false;
        }else{
            //生成ctrl类
            $ctrl = controller(CONTROLLER_NAME,CONTROLLER_PATH); 
        }
        if(!$ctrl) {

        }else{
            // 获取当前操作名 支持动态路由
            if(!isset($action)){
                $action    =   ACTION_NAME.C('ACTION_SUFFIX');  
            }
            try{
                self::invokeAction($ctrl,$action);
            } catch (\ReflectionException $e) { 
                // 方法调用发生异常后 引导到__call方法处理
                $method = new \ReflectionMethod($ctrl,'__call');
                $method->invokeArgs($module,array($action,''));
            }
            return ;
        }
    }

     /**
     * 加载控制器类的方法
     * @access public
     * @return void
     */
    public static function invokeAction($ctrl,$action){
        if(!preg_match('/^[A-Za-z](\w)*$/',$action)){
            // 非法操作
            throw new \ReflectionException();
        }
        //执行当前操作
        $method =   new \ReflectionMethod($ctrl, $action);
        if($method->isPublic() && !$method->isStatic()){
            //执行一个反射的方法。
            $method->invoke($ctrl);
        }else{
            // 操作方法不是Public或者是静态的 抛出异常
            throw new \ReflectionException();
        }
    }    
}